"""
URL builder utility for notification callback links.

This module builds HTTP/HTTPS URLs that are included in notifications for users
to click on (e.g., https://myapp.com/research/123). This is separate from
Apprise service URLs which use their own protocols (discord://, mailto://, etc.).

Uses the existing security URL validator for consistency with the rest of the application.
"""

from typing import Optional
from loguru import logger

from ..security.url_builder import (
    build_base_url_from_settings,
    build_full_url,
)
from ..security.url_validator import URLValidator, URLValidationError


def build_notification_url(
    path: str,
    settings_manager=None,
    settings_snapshot: Optional[dict] = None,
    fallback_base: str = "http://localhost:5000",
    validate: bool = True,
) -> str:
    """
    Build a full HTTP/HTTPS callback URL for use in notifications.

    This builds URLs that users can click on from notifications to return to
    the application (e.g., https://myapp.com/research/123). This is separate
    from Apprise service URLs which use their own protocols.

    Args:
        path: Relative path (e.g., "/research/123")
        settings_manager: Optional SettingsManager instance to get external_url
        settings_snapshot: Optional settings snapshot dict (alternative to settings_manager)
        fallback_base: Fallback base URL if no setting configured
        validate: Whether to validate the constructed URL (default: True)

    Returns:
        Full HTTP/HTTPS URL (e.g., "https://myapp.com/research/123")

    Raises:
        URLValidationError: If validate=True and URL is invalid

    Note:
        You can provide either settings_manager OR settings_snapshot, not both.
        settings_snapshot is preferred for thread-safe background tasks.
    """
    try:
        # Extract settings from snapshot or manager
        external_url = None
        host = None
        port = None

        if settings_snapshot:
            external_url = settings_snapshot.get("app.external_url", "")
            host = settings_snapshot.get("app.host", "localhost")
            port = settings_snapshot.get("app.port", 5000)
        elif settings_manager:
            external_url = settings_manager.get_setting(
                "app.external_url", default=""
            )
            host = settings_manager.get_setting("app.host", default="localhost")
            port = settings_manager.get_setting("app.port", default=5000)

        # Build base URL using the centralized utility
        base_url = build_base_url_from_settings(
            external_url=external_url,
            host=host,
            port=port,
            fallback_base=fallback_base,
        )

        # Build full URL
        full_url = build_full_url(
            base_url=base_url,
            path=path,
            validate=False,  # We'll validate with our own validator
        )

        # Validate if requested using the security module validator
        if validate:
            URLValidator.validate_http_url(full_url)

        return full_url

    except Exception as e:
        if isinstance(e, URLValidationError):
            raise

        logger.exception(
            f"Failed to build notification URL for path '{path}': {e}"
        )
        raise URLValidationError(f"Failed to build notification URL: {e}")
